macのオレオレGyazo client
ほとんどの人には不要
2026/4/17
公式クライアントが撮影後に「なにもしない」オプションを実装したのでいよいよいらなくなりつつある 神
細かいことを言うとウィンドウキャプチャ時の余白と、撮影後にそれでもフォーカスを奪われる問題はあるので、使い出がなくはないが…
これはもう内部で使っているキャプチャ方式を変えるとかじゃないとダメだろうし厳しそう
ユースケース、作成理由は最下方参照
導入手順
1. Gyazoのアクセストークンを発行する
2. hammerspoonをinstallする
3. OSの設定からアクセシビリティと画面録画の権限をhammerspoonに付与する
4. hammerspoon右クリ→open configし、後述のluaを貼り付ける(tokenは編集が必要)
5. reload configする
Lets 撮影
ctrl shift 1でwindow
ctrl shift 2で範囲選択
末尾で適当にバインドしてね
うまく動いてない時はHammerspoonのConsole開いてログを見る
HammerspoonGyazo 変更ログ
最終更新2025/3/9
code:init.lua
-- 設定
local gyazoToken = "YOUR_ACCESS_TOKEN" -- gyazoのアクセストークン(必須)
local accessPolicy = "anyone" -- Gyazoアクセス権限設定
local metadataIsPublic = "false" -- メタデータ公開設定
local defaultAppName = "Hammerspoon Screenshot" -- デフォルトのアプリ名
local defaultRefererUrl= "" -- 取得URLがない場合のデフォルトURL
local desc = "" -- 説明文
local collectionId = "" -- コレクションID
local copyPermalinkToClipboard = true -- URLをクリップボードにコピー
-- URL取得を試みる対象ブラウザを設定(SafariとChromiumでURL取得メソッドが変わるので注意)
local safariLikeBrowsers = {"Safari"}
local chromiumLikeBrowsers = {"Google Chrome", "Vivaldi"}
-- URL取得するのか判定
local function isInList(appName, browserList)
for _, name in ipairs(browserList) do
if appName == name then
return true
end
end
return false
end
-- 通知表示
local function notify(msg)
hs.notify.new({title = "Gyazo", informativeText = msg}):send()
end
-- UUID生成
local function generateUUID()
local uuid = hs.execute("uuidgen")
return uuid:gsub("%s+", "")
end
-- 画像をリサイズ(半分)して指定パスに保存
local function processAndSaveImage(image, filePath)
local origSize = image:size()
local newSize = { w = origSize.w / 2, h = origSize.h / 2 }
local resizedImage = image:setSize(newSize)
if not resizedImage or not resizedImage:saveToFile(filePath, "jpg") then
notify("画像のリサイズ/保存に失敗しました")
return false
end
return true
end
-- ブラウザのアクティブなタブからURLを取得
local function getBrowserURL(appName)
local script
if isInList(appName, safariLikeBrowsers) then
script = string.format([[
try
tell application "%s"
if (count of windows) > 0 then
return URL of current tab of front window
else
return ""
end if
end tell
on error
return ""
end try
]], appName)
elseif isInList(appName, chromiumLikeBrowsers) then
script = string.format([[
try
tell application "%s"
if (count of windows) > 0 then
return URL of active tab of front window
else
return ""
end if
end tell
on error
return ""
end try
]], appName)
else
return nil
end
local ok, url = hs.osascript.applescript(script)
if ok and url and url ~= "" then
return url
else
return nil
end
end
-- Gyazoへ画像をアップロード
local function uploadImage(filePath, title, fileName, appNameParam)
local attr = hs.fs.attributes(filePath)
if not attr then
notify("ファイルが存在しません: " .. filePath)
return
end
local browserURL = getBrowserURL(appNameParam)
local finalRefererUrl = browserURL or defaultRefererUrl
local curlArgs = {
"--form-string", "access_token=" .. gyazoToken,
"--form-string", "access_policy=" .. accessPolicy,
"--form-string", "metadata_is_public=" .. metadataIsPublic,
"--form-string", "app=" .. (appNameParam or defaultAppName),
"--form-string", "title=" .. title,
"--form-string", "created_at=" .. tostring(os.time()),
"--form-string", "referer_url=" .. finalRefererUrl,
"--form-string", "desc=" .. desc,
"--form-string", "collection_id=" .. collectionId,
"-F", "imagedata=@" .. filePath .. ";filename=" .. fileName,
"https://upload.gyazo.com/api/upload"
}
hs.task.new("/usr/bin/curl", function(exitCode, stdOut, stdErr)
if exitCode ~= 0 then
notify("Gyazo アップロードに失敗しました")
else
local response = hs.json.decode(stdOut)
if response and response.permalink_url then
if copyPermalinkToClipboard then
hs.pasteboard.setContents(response.permalink_url)
notify("Gyazo URL をクリップボードへコピーしました")
else
notify("Gyazo URL: " .. response.permalink_url)
end
else
notify("アップロード結果の解析に失敗しました")
end
os.remove(filePath)
end
end, curlArgs):start()
end
-- フォーカス中のウィンドウをキャプチャ
local function captureWindow()
local win = hs.window.focusedWindow()
if not win then
notify("フォーカス中のウィンドウがありません")
return
end
local originalTitle = win:title() or "untitled"
local fileName = "screenshot_" .. generateUUID() .. ".jpg"
local filePath = os.getenv("HOME") .. "/Desktop/" .. fileName
local appNameForUpload = (win:application() and win:application():name()) or defaultAppName
local image = win:snapshot()
if not image then
notify("ウィンドウキャプチャに失敗しました")
return
end
if processAndSaveImage(image, filePath) then
-- スクリーンショット音を再生
hs.sound.getByFile("/System/Library/Components/CoreAudio.component/Contents/SharedSupport/SystemSounds/system/Grab.aif"):play()
uploadImage(filePath, originalTitle, fileName, appNameForUpload)
end
end
-- 範囲選択キャプチャ
local function captureSelection()
local frontWin = hs.window.focusedWindow()
local storedTitle, storedAppName
if frontWin then
storedTitle = frontWin:title()
storedAppName = frontWin:application() and frontWin:application():name() or defaultAppName
else
local frontApp = hs.application.frontmostApplication()
storedTitle = frontApp and frontApp:name() or "Screenshot"
storedAppName = frontApp and frontApp:name() or defaultAppName
end
local fileName = "screenshot_range_" .. generateUUID() .. ".jpg"
local filePath = os.getenv("HOME") .. "/Desktop/" .. fileName
hs.timer.doAfter(0.1, function()
hs.execute("screencapture -i " .. string.format('"%s"', filePath))
if hs.fs.attributes(filePath) then
local image = hs.image.imageFromPath(filePath)
if image and processAndSaveImage(image, filePath) then
uploadImage(filePath, storedTitle, fileName, storedAppName)
end
end
end)
end
-- ホットキー登録
hs.hotkey.bind({"ctrl", "shift"}, "1", captureWindow) -- Ctrl+Shift+1 → ウィンドウキャプチャ
hs.hotkey.bind({}, "f1", captureWindow) -- F1 → ウィンドウキャプチャ
hs.hotkey.bind({"ctrl", "shift"}, "2", captureSelection) -- Ctrl+Shift+2 → 範囲選択キャプチャ
hs.hotkey.bind({}, "f10", captureSelection) -- F10 → 範囲選択キャプチャ
経緯と思想
2025/2/7
macでHammerspoonを使ったalternative Gyazoクライアント
MapleLegends用としてchatGPT.icon3mini-highに作って貰った
公式クライアントが爆速になったら不要になる予定
mouii.iconはGyazo proユーザだから場合によっては使い勝手変わるかも
公式のGyazo for macには以下の問題があり…
撮影後にポップアップが出てきて邪魔や!!!!!!!!!!!
いいかんじになった模様
gyazo on macだと動作が遅いためキーダウンから撮影までのタイミングがズレる
いいかんじになりつつある模様
Gyazo Desktopがブラウザの情報を取得してくれないにより、画像のメタデータがなにも付記されない
Chrome/Vivaldiだとブラウザのページ名まで取得できるがマイナーブラウザだと無理とか
ウィンドウタイトルじゃなくてよくわからんapp名しか拾わないとか→なくなった?
いいかんじになった模様
あと、ウィンドウの周りに意味不明な余白が出来る事もあった
これはwindowのスクショをapplescriptのscreenshot -lみたいなので取得すると発生するらしいですね…
要望を送ったけど待ってられないし、自分で実現できそうならするべきニャンね!
applescriptとかautomatorでやろうとしてもショートカットではscreenshotの取得ができなかった…のでhammerspoon
サンプル画像(metadata公開設定)
https://gyazo.com/cd82fcc58e128a0fc56fb0bcbb2aee41ウィンドウ
githubって何かめんどくさくて…
mac app
public.icon